package com.szwistar.common.datastruct;

import com.fasterxml.jackson.annotation.JsonIgnore;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 一种类似于操作系统文件目录的 "分类目录" 数据结构
 * 如全称为 "交通工具/车辆/汽车" 的分类，会分解成 "交通工具" -> "车辆" -> "汽车" 这 3 个有层级关系的分类
 */
public class Catagory {
	// 全局分类名 fullname <-> Catagory 映射表
	static Map<String, Catagory> all = new HashMap<String, Catagory>();
	// 根分类
	public static final Catagory ROOT = new Catagory(null, "");

	// 父分类目录
	Catagory parent;
	// 本分类目录名
	String name;
	// 此类别所包含的子类别
	List<Catagory> children;

	/**
	 * 分解全称字符串并创建相应的分类（如果上级分类不存在，则先创建上级分类）
	 * @param fullname 分类全称
	 * @return 叶子分类
	 */
	public static Catagory getOrCreate(String fullname) {
		// 去掉所有的前后空格
		fullname = fullname.trim();
		// 把所有的 "\" 转化为 "/"
		fullname = fullname.replace("\\", "/");
		// 去掉最后面的"/"
		while(fullname.endsWith("/")) {
			fullname = fullname.substring(0, fullname.length() - 1);
		}

		if(all.get(fullname) != null) {
			return all.get(fullname);
		}

		int pos = fullname.lastIndexOf("/");

		// 是否是根目录
		if(pos < 0) { return new Catagory(ROOT, fullname); }

		String parentName = fullname.substring(0, pos);
		Catagory parent = getOrCreate(parentName);
		String name = fullname.substring(pos+1);
		return new Catagory(parent, name);
	}

	private Catagory(Catagory parent, String name) {
		this.name = name;
		this.parent = parent;
		if(parent != null) { parent.addChild(this); }
		all.put(getFullname(), this);
	}

	public String getName() { return name; }
	public void setName(String name) { this.name = name; }
	@JsonIgnore
	public Catagory getParent() { return parent; }
	public void setParent(Catagory parentCatagory) { this.parent = parentCatagory; }
	public List<Catagory> getChildren() { return children; }

	/**
	 * 添加子分类
	 */
	public void addChild(Catagory child) {
		if(children == null) { children = new ArrayList<Catagory>(); }
		children.add(child);
	}

	public String getFullname() {
		if(parent == null) { return ""; }
		String parentFullname = parent.getFullname();
		return parentFullname + "/" + name;
	}

	@Override
	public String toString() { return getFullname(); }
}
